/**
 * Copyright 2007-2008. Chongqing First Information & Network Co., Ltd. All
 * rights reserved. <a>http://www.cqfirst.com.cn</a>
 */
package com.cqcis.uip.base.framework.utils;

import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

/**
 * XML文件解析工具类
 * 
 * @author huangmy
 * @date   2007-12-24
 */
public class XmlParseUtil {
	private static Log log = LogFactory.getLog(XmlParseUtil.class);
	
	/**
	 * 获取给定XML文件字符串的Document
	 * 
	 * @param xml
	 * @return
	 */
	public static Document get(String xml) throws Exception {
		Reader in = new StringReader(xml);
		SAXReader reader = new SAXReader();
		try {
			return reader.read(in);
		} catch (Exception e) {
			log.error("Catch Exception in parse xml: " + xml, e);
			throw e;
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (Exception e) {					
				}
			}
		}
	}
	
	/**
	 * 获取给定输入xml文件流的Document
	 * 
	 * @param in
	 * @return
	 * @throws Exception
	 */
	public static Document get(InputStream in) throws Exception {
		SAXReader reader = new SAXReader();
		try {
			return reader.read(in);
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (Exception e) {					
				}
			}
		}		
	}
	
	/**
	 * 获取文档的根节点
	 * @param document
	 * @return
	 */
	public static Element getRootElement(Document document) {
		return document == null ? null : document.getRootElement();
	}
	
	/**
	 * 获取指定节点上的属性值
	 * @param element
	 * @param attributeName
	 * @return
	 */
	public static String getAttributeValue(Element element, String attributeName) {
		return element == null ? null : element.attributeValue(attributeName);
	}
	
	/**
	 * 获取节点名称
	 * @param element
	 * @return
	 */
	public static String getElementName(Element element) {
		return element == null ? null : element.getName();
	}
	
	/**
	 * 获取节点全名
	 * @param element
	 * @return
	 */
	public static String getElementQualifiedName(Element element) {
		return element == null ? null : element.getQualifiedName();
	}
	
	/**
	 * 获取节点文本值
	 * @param element
	 * @return
	 */
	public static String getElementTextTrim(Element element) {
		return element == null ? null : element.getTextTrim();
	}
	
	/**
	 * 获取当前节点指定名称的子节点集
	 * @param element
	 * @param childName
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static List<Element> getChildElements(Element element, String childName) {
		if (element == null || !StringUtil.hasText(childName)) {
			throw new NullPointerException("the element or childName can't be null.");
		}
				
		List<Element> list = new ArrayList<Element>();
		
		for (Iterator<Element> it = element.elementIterator(childName); it.hasNext();) {
			Element ce = it.next();	
			
			list.add(ce);
		}
		
		return list.size() == 0 ? null : list;
	}
	
	/**
	 * 获取节点指定名称的子节点
	 * @param element
	 * @param childName
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static Element getChildElement(Element element, String childName) {
		if (element == null || !StringUtil.hasText(childName)) {
			throw new NullPointerException("the element or childName can't be null.");
		}
				
		for (Iterator<Element> it = element.elementIterator(childName); it.hasNext();) {
			return it.next();
		}
		
		return null;
	}
	
	/**
	 * 返回节点的子节点集
	 * @param element
	 * @param childName
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static Map<String, Element> getChildElementMap(Element element) {
		if (element == null) {
			throw new NullPointerException("the element can't be null.");
		}
		
		Map<String, Element> elements = new HashMap<String, Element>();
		
		for (Iterator<Element> it = element.elementIterator(); it.hasNext();) {
			Element ce = it.next();	
			
			elements.put(getElementName(ce), ce);
		}
		
		return elements;
	}
}
